// 引入axios
import axios from 'axios'
// 注意：在vue组件中，通过this可以代表当前组件 如果在一个js文件中，this是无法代表某一个组件的
// 如果在一个vue组件中。可以通过this.$store直接访问store对象，但是如果在一个普通模块（js），没有this，需要手动的导入store
import store from '@/store/index'
// 引入路由
import router from '@/router'
// 引入提示框组件
import { Toast } from 'vant'
// 引入json-bigint
import JSONbig from 'json-bigint'
// 创建request实例
// 定义根路径
const baseURL = 'http://toutiao-app.itheima.net'
// const baseURL = 'http://192.168.74.56:8000'
const request = axios.create({
  // 配置根路径和超时时间
  baseURL,
  timeout: 5000,
  // `transformResponse` 在传递给 then/catch 前，允许修改响应数据
  transformResponse: [function (data) {
    // 对 data 进行任意转换处理
    // 可能会报错，有可能后台返回的不是json所以要用try catch
    try {
      return JSONbig.parse(data)
    } catch {
      return data
    }
  }]
})

// 添加请求拦截器
request.interceptors.request.use(function (config) {
  // 在发送请求之前做些什么
  // 赋值给token  从vuex中找token，
  const token = store.state.user.token.token
  // 如果有token证明登录了，之后的请求都可以带上token
  if (token) {
    config.headers.Authorization = 'Bearer ' + token
  }
  // 请求信息 config
  return config
}, function (error) {
  // 对请求错误做些什么
  return Promise.reject(error)
})

// 添加响应拦截器
request.interceptors.response.use(function (response) {
  // 对响应数据做点什么
  return response.data // 增加data，返回的结果就很干净
}, async function (error) {
  // 对响应错误做点什么
  console.dir(error)
  // 1. 配置axios的响应拦截器
  // 2. 通过响应拦截器捕获401异常
  // 3. 判断`error.response.status`是否是401
  // 4. 如果不是401，说明不是由于token过期导致，不管。
  // 5. 如果错误码是401，说明token过期了
  // 6. 判断vuex中是否有refresh_token。
  // 7. 如果没有，直接拦截到登录页面（删除vuex中token，跳转到登录页，提示）
  // 8. 如果有refresh_token， 拿着刷新token重新新的token。
  // 9. 如果成功了，获取到新的token，并且更新到vuex中。重新发送一个请求（才能保证用户无感）
  // 10. 如果失败了，直接拦截到登录页面（删除vuex中token，跳转到登录页，提示）
  const { status } = error.response
  const refreshToken = store.state.user.token.refresh_token
  if (status === 401) {
    if (refreshToken) {
      try {
        const res = await axios({
          method: 'put',
          url: baseURL + '/v1_0/authorizations',
          headers: {
            Authorization: 'Bearer ' + refreshToken
          }
        })
        store.commit('user/setToken', {
          token: res.data.data.token,
          refresh_token: refreshToken
        })
        return request(error.config)
      } catch {
        store.commit('user/removeToken')
        router.push({
          path: '/login',
          query: {
            back: router.currentRoute.path
          }
        })
        Toast.fail('登录信息失效')
      }
    } else {
      store.commit('user/removeToken')
      router.push({
        path: '/login',
        query: {
          back: router.currentRoute.path
        }
      })
      Toast.fail('登录信息失效')
    }
  } else {
    return Promise.reject(error)
  }
})
// 导出
export default request
